package com.deanlib.cabinet.base;

import androidx.annotation.NonNull;

import com.deanlib.cabinet.data.network.Response;
import com.deanlib.cabinet.data.network.ResponseTransformer;
import com.deanlib.cabinet.data.network.schedulers.SchedulerProvider;

import java.util.Optional;

import io.reactivex.Observable;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import io.reactivex.internal.functions.Functions;

/**
 * Created by Dean on 2021/6/19
 */
public class NetworkAuxiliary implements INetworkAuxiliary{

    private CompositeDisposable mCompositeDisposable;
    private final IPopupAuxiliary mPopupAuxiliary;

    public NetworkAuxiliary(IPopupAuxiliary popupAuxiliary){
        mPopupAuxiliary = popupAuxiliary;
    }

    @Override
    public <T> void request(@NonNull Observable<Response<T>> observable, Consumer<Optional<T>> next){
//        request(observable, next, Functions.ON_ERROR_MISSING);
        request(observable, next, err->{
            if (mPopupAuxiliary!=null) {
                mPopupAuxiliary.toast(err.getMessage());
            }
        });
    }

    @Override
    public <T> void request(@NonNull Observable<Response<T>> observable, Consumer<Optional<T>> next,
                            Consumer<? super Throwable> error){
        request(observable, next, error, Functions.EMPTY_ACTION);
    }

    @Override
    public <T> void request(@NonNull Observable<Response<T>> observable, Consumer<Optional<T>> next,
                            Consumer<? super Throwable> error, Action complete){
        if (mCompositeDisposable == null){
            synchronized (this){
                if (mCompositeDisposable == null){
                    mCompositeDisposable = new CompositeDisposable();
                }
            }
        }
        mCompositeDisposable.add(observable.compose(ResponseTransformer.handleResult(mPopupAuxiliary))
                .compose(SchedulerProvider.getInstance().applySchedulers())
                .doOnSubscribe(disposable -> {
                    //被订阅时，也就是执行前被调用
                    if (mPopupAuxiliary!=null) {
                        mPopupAuxiliary.loading(null, null);
                    }
                })
                .doFinally(()->{
                    //无论正常或异常，结束时调用
                    if (mPopupAuxiliary!=null) {
                        mPopupAuxiliary.loaded();
                    }
                }).subscribe(next, error, complete));
    }

    @Override
    public void dispose(){
        if (mCompositeDisposable != null) {
            mCompositeDisposable.dispose();
        }
    }
}
